#include "attendancemanager.h"

#include "attendancetimemanager.h"

#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>
#include <QDate>
#include <QDateTime>

AttendanceManager::AttendanceManager(QSqlDatabase &db, QObject *parent)
    : QObject{parent}
    , m_db(db)
{
    // 默认平日设置（可根据实际情况调整）
    m_weekdaySettings.startTime = QTime(9, 0, 0);
    m_weekdaySettings.endTime   = QTime(18, 0, 0);
}

// 设置平日打卡时间设置
void AttendanceManager::setWeekdaySettings(const ClockingTime &settings) {
    m_weekdaySettings = settings;
}

// 获取当前日期的字符串形式
QString AttendanceManager::currentDate() const
{
    return QDate::currentDate().toString("yyyy-MM-dd");
}

// 获取当前日期的打卡设置
ClockingTime AttendanceManager::getDailySettings(const QDate &date) {

    // 获取当前日期是周几
    const int weekday = date.dayOfWeek();
    QString weekdayStr = AttendanceTimeManager::m_weekdayMap.value(weekday);    // 获取索引对应的星期几
    DailySettings settings = AttendanceTimeManager::m_settings.value(weekdayStr);    // 获取星期几对应的打卡设置

    m_weekdaySettings.startTime = settings.startTime;
    m_weekdaySettings.endTime = settings.endTime;

    return m_weekdaySettings;
}

// 根据员工卡号获取员工ID
bool AttendanceManager::getEmployeeId(const QString &rfidCard, int &empId) {
    if (!m_db.isOpen()) {
        qWarning() << "数据库未连接";
        return false;
    }
    QSqlQuery query(m_db);
    query.prepare("SELECT emp_id FROM employee WHERE card_id = ?");
    query.addBindValue(rfidCard);
    if (!query.exec() || !query.next()) {
        qWarning() << "查询员工失败或未找到员工，卡号:" << rfidCard;
        return false;
    }
    empId = query.value(0).toInt();
    return true;
}
// 获取当日考勤记录
bool AttendanceManager::getTodayAttendanceRecord(int empId, int &attId, bool &hasRecord, QVariant &clockOut) {
    QSqlQuery query(m_db);
    query.prepare("SELECT att_id, clock_in, clock_out FROM attendance WHERE emp_id = ? AND check_date = DATE('now')");
    query.addBindValue(empId);
    if (!query.exec()) {
        qWarning() << "查询考勤记录失败:" << query.lastError().text();
        return false;
    }
    hasRecord = query.next();
    if (hasRecord) {
        attId = query.value("att_id").toInt();
        clockOut = query.value("clock_out");
    }
    return true;
}
// 上班打卡
bool AttendanceManager::punchIn(int empId, const ClockingTime &settings, const QDateTime &clockTime, int &newAttId) {
    QSqlQuery insertQuery(m_db);
    insertQuery.prepare(
        "INSERT INTO attendance (emp_id, check_date, clock_in, status) "
        "VALUES (?, DATE('now'), ?, "
        "   CASE WHEN TIME(?) > ? THEN '迟到' ELSE '正常' END)"
        );
    insertQuery.addBindValue(empId);
    insertQuery.addBindValue(clockTime.toString("yyyy-MM-dd hh:mm:ss"));
    insertQuery.addBindValue(clockTime.toString("hh:mm:ss"));
    insertQuery.addBindValue(settings.startTime.toString("hh:mm:ss"));
    if (!insertQuery.exec()) {
        qWarning() << "上班打卡失败:" << insertQuery.lastError().text();
        return false;
    }
    newAttId = insertQuery.lastInsertId().toInt();
    qDebug() << "上班打卡成功，员工ID:" << empId;
    return true;
}
// 下班打卡
bool AttendanceManager::punchOut(int attId, const ClockingTime &settings, const QDateTime &clockTime) {
    QSqlQuery updateQuery(m_db);
    updateQuery.prepare(
        "UPDATE attendance SET clock_out = ?, "
        "status = CASE WHEN TIME(?) < ? THEN '早退' "  // 如果早退则标记
        "         ELSE (CASE WHEN status = '早退' THEN '正常' ELSE status END) END "  // 否则检查原状态
        "WHERE att_id = ?"
        );
    updateQuery.addBindValue(clockTime.toString("yyyy-MM-dd hh:mm:ss"));  // 绑定下班时间
    updateQuery.addBindValue(clockTime.toString("hh:mm:ss"));            // 提取打卡时间的时分秒
    updateQuery.addBindValue(settings.endTime.toString("hh:mm:ss"));     // 绑定预设下班时间
    updateQuery.addBindValue(attId);                                     // 考勤记录ID

    if (!updateQuery.exec()) {
        qWarning() << "下班打卡失败:" << updateQuery.lastError().text();
        return false;
    }
    qDebug() << "下班打卡成功，考勤记录ID:" << attId;
    return true;
}

// 考勤打卡
ClockResult AttendanceManager::clockInOut(const QString &rfidCard) {
    ClockResult result;
    result.clockTime = QDateTime::currentDateTime();

    if (!m_db.isOpen()) {
        result.success = false;
        result.message = "数据库未连接";
        return result;
    }

    // 开启事务
    if (!m_db.transaction()) {
        result.success = false;
        result.message = "无法开启数据库事务";
        return result;
    }

    try {
        int empId = 0;
        if (!getEmployeeId(rfidCard, empId)) {
            emit employeeCard(rfidCard);    // 发送卡号

            throw std::runtime_error("无效的卡号或员工不存在");
        }

        int attId = 0;
        bool hasRecord = false;
        QVariant clockOut;
        if (!getTodayAttendanceRecord(empId, attId, hasRecord, clockOut)) {
            throw std::runtime_error("考勤查询失败");
        }

        // 根据当前日期获取对应打卡设置
        ClockingTime settings = getDailySettings(result.clockTime.date());

        if (hasRecord) {
            
            // 下班打卡
            if (!punchOut(attId, settings, result.clockTime)) {
                throw std::runtime_error("下班打卡失败");
            }
            result.success = true;
            result.clockType = "下班";
            result.message = "下班打卡成功";
            
            // 已有考勤记录，判断是否已完成下班打卡
            if(!clockOut.isNull()){
                // 重复打卡
                result.success = true;
                result.clockType = "重复打卡";
                result.message = "已完成当日考勤记录";
            }
        } else {
            // 执行上班打卡（插入新记录）
            int newAttId = 0;
            if (!punchIn(empId, settings, result.clockTime, newAttId)) {
                throw std::runtime_error("上班打卡失败");
            }
            result.success = true;
            result.clockType = "上班";
            result.message = "上班打卡成功";
        }

        if (!m_db.commit()) {
            throw std::runtime_error("事务提交失败");
        }
    } catch (const std::exception &e) {
        m_db.rollback();
        result.success = false;
        result.message = QString("操作失败: %1").arg(e.what());
    }

    return result;
}
